﻿using System;

namespace Loki
{
    /// <summary>
    /// Common interface for object contexts.
    /// </summary>
    public interface IObjectContext : IDisposable
    {
        /// <summary>
        /// Loads the additional definitions.
        /// </summary>
        /// <param name="P_ObjectDefinitionURI">The object definition URI.</param>
        void LoadContext(params string[] P_ObjectDefinitionURI);

        void DefineType<T>(string P_Name, Func<T> P_Builder, bool P_IsSingleton);

        void DefineType<T>(string P_Name, bool P_IsSingleton) where T : new();

        /// <summary>
        /// Injects a singleton in the context.
        /// </summary>
        /// <typeparam name="T">Instance type.</typeparam>
        /// <param name="P_Name">Name of the instance.</param>
        /// <param name="P_Instance">The instance.</param>
        void InjectSingleton<T>(string P_Name, T P_Instance);

        /// <summary>
        /// Marks the context as loaded (no additional object definition allowed).
        /// </summary>
        void EndLoad();

        /// <summary>
        /// Gets an instance of type <typeparamref name="T"/> as defined in the configuration.
        /// </summary>
        /// <typeparam name="T">The object type.</typeparam>
        /// <param name="P_ObjectName">Name of the object.</param>
        /// <returns>The object.</returns>
        T GetObject<T>(string P_ObjectName);

        /// <summary>
        /// Determines whether the object with the specified name is defined.
        /// </summary>
        /// <param name="P_ObjectName">Name of the object.</param>
        /// <returns>
        ///   Returns <c>true</c> if the object with the specified name is defined; otherwise, <c>false</c>.
        /// </returns>
        bool IsDefined(string P_ObjectName);
    }
}
